home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / RTrace 1.0 / source / patch1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-16  |  7.0 KB  |  197 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * This code received contributions from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *
  11.  * Redistribution and use in source and binary forms are permitted
  12.  * provided that the above copyright notice and this paragraph are
  13.  * duplicated in all such forms and that any documentation,
  14.  * advertising materials, and other materials related to such
  15.  * distribution and use acknowledge that the software was developed
  16.  * by Antonio Costa, at INESC-Norte. The name of the author and
  17.  * INESC-Norte may not be used to endorse or promote products derived
  18.  * from this software without specific prior written permission.
  19.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  21.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  22.  */
  23. #include "defs.h"
  24. #include "extern.h"
  25.  
  26. /**********************************************************************
  27.  *    RAY TRACING - Patch (part2) - Version 7.3.2                     *
  28.  *                                                                    *
  29.  *    MADE BY    : Antonio Costa, INESC-Norte, October 1988           *
  30.  *    ADAPTED BY : Antonio Costa, INESC-Norte, June 1989              *
  31.  *    MODIFIED BY: Antonio Costa, INESC-Norte, August 1992            *
  32.  **********************************************************************/
  33.  
  34. /***** Patch *****/
  35. #include "patch.h"
  36.  
  37. void
  38. patch_normal(position, object, normal)
  39.   xyz_ptr         position;
  40.   object_ptr      object;
  41.   xyz_ptr         normal;
  42. {
  43.   REG real        u, v, b0, b1, b2, b3;
  44.   xyz_struct      dfu, dfv, k0, k1, k2, k3, k4, k5, k6, k7;
  45.   patch_ptr       patch;
  46.  
  47.   patch = (patch_ptr) object->data;
  48.   u = patch->u_hit;
  49.   v = patch->v_hit;
  50.   /* 1st partial derivative (u) */
  51.   b0 = BLEND0(v);
  52.   b1 = BLEND1(v);
  53.   CUBIC(patch, 1, v, k1);
  54.   CUBIC(patch, 3, v, k3);
  55.   MULTIPLY(patch->p[3]->coords, b0, k4);
  56.   MULTIPLY(patch->p[4]->coords, b0, k5);
  57.   MULTIPLY(patch->p[7]->coords, b1, k6);
  58.   MULTIPLY(patch->p[8]->coords, b1, k7);
  59.   SUBTRACT(k1, k4, k6, k1);
  60.   SUBTRACT(k3, k5, k7, k3);
  61.   DERIV_CUBIC(patch, 0, u, k0);
  62.   DERIV_CUBIC(patch, 2, u, k2);
  63.   b2 = DERIV_BLEND0(u);
  64.   b3 = DERIV_BLEND1(u);
  65.   dfu.x = k0.x * b0 + k1.x * b2 + k2.x * b1 + k3.x * b3;
  66.   dfu.y = k0.y * b0 + k1.y * b2 + k2.y * b1 + k3.y * b3;
  67.   dfu.z = k0.z * b0 + k1.z * b2 + k2.z * b1 + k3.z * b3;
  68.   /* 2nd partial derivative (v) */
  69.   b0 = BLEND0(u);
  70.   b1 = BLEND1(u);
  71.   CUBIC(patch, 0, u, k0);
  72.   CUBIC(patch, 2, u, k2);
  73.   MULTIPLY(patch->p[3]->coords, b0, k4);
  74.   MULTIPLY(patch->p[4]->coords, b1, k5);
  75.   MULTIPLY(patch->p[7]->coords, b0, k6);
  76.   MULTIPLY(patch->p[8]->coords, b1, k7);
  77.   SUBTRACT(k0, k4, k5, k0);
  78.   SUBTRACT(k2, k6, k7, k2);
  79.   DERIV_CUBIC(patch, 1, v, k1);
  80.   DERIV_CUBIC(patch, 3, v, k3);
  81.   b2 = DERIV_BLEND0(v);
  82.   b3 = DERIV_BLEND1(v);
  83.   dfv.x = k0.x * b2 + k1.x * b0 + k2.x * b3 + k3.x * b1;
  84.   dfv.y = k0.y * b2 + k1.y * b0 + k2.y * b3 + k3.y * b1;
  85.   dfv.z = k0.z * b2 + k1.z * b0 + k2.z * b3 + k3.z * b1;
  86.   CROSS_PRODUCT(*normal, dfu, dfv);
  87.   NORMALIZE(*normal);
  88. }
  89. static void
  90. load_patch(patch, i, i0, i1, i2, i3)
  91.   patch_ptr       patch;
  92.   int             i, i0, i1, i2, i3;
  93. {
  94.   xyz_struct      p0, p1, p2, p3;
  95.  
  96.   STRUCT_ASSIGN(p0, patch->p[i0]->coords);
  97.   STRUCT_ASSIGN(p1, patch->p[i1]->coords);
  98.   STRUCT_ASSIGN(p2, patch->p[i2]->coords);
  99.   STRUCT_ASSIGN(p3, patch->p[i3]->coords);
  100.   patch->c[0][i].x = (-p0.x + 3.0 * p1.x - 3.0 * p2.x + p3.x) * 0.5;
  101.   patch->c[1][i].x = (2.0 * p0.x - 5.0 * p1.x + 4.0 * p2.x - p3.x) * 0.5;
  102.   patch->c[2][i].x = (-p0.x + p2.x) * 0.5;
  103.   patch->c[3][i].x = p1.x;
  104.   patch->c[0][i].y = (-p0.y + 3.0 * p1.y - 3.0 * p2.y + p3.y) * 0.5;
  105.   patch->c[1][i].y = (2.0 * p0.y - 5.0 * p1.y + 4.0 * p2.y - p3.y) * 0.5;
  106.   patch->c[2][i].y = (-p0.y + p2.y) * 0.5;
  107.   patch->c[3][i].y = p1.y;
  108.   patch->c[0][i].z = (-p0.z + 3.0 * p1.z - 3.0 * p2.z + p3.z) * 0.5;
  109.   patch->c[1][i].z = (2.0 * p0.z - 5.0 * p1.z + 4.0 * p2.z - p3.z) * 0.5;
  110.   patch->c[2][i].z = (-p0.z + p2.z) * 0.5;
  111.   patch->c[3][i].z = p1.z;
  112. }
  113. void
  114. patch_enclose(object)
  115.   object_ptr      object;
  116. {
  117. #define INTERVALS  (4)
  118. #define CORRECTION ((real) 0.15)/* 15% correction */
  119.  
  120.   REG int         i, j;
  121.   REG real        u, v, b0, b1, b2, b3;
  122.   xyz_struct      temp, f, k0, k1, k2, k3, k4, k5, k6, k7, center;
  123.   patch_ptr       patch;
  124.  
  125.   patch = (patch_ptr) object->data;
  126.   if (object->transf != NULL)
  127.   {
  128.     for (; patch->vertex != NULL;
  129.          patch->vertex = (vertex_ptr) patch->vertex->next)
  130.     {
  131.       transform(object->inv_transf, &(patch->vertex->coords), &temp);
  132.       STRUCT_ASSIGN(patch->vertex->coords, temp);
  133.     }
  134.     FREE(object->transf);
  135.     object->transf = NULL;
  136.   }
  137.   load_patch(patch, 0, 2, 3, 4, 5);
  138.   load_patch(patch, 1, 0, 3, 7, 10);
  139.   load_patch(patch, 2, 6, 7, 8, 9);
  140.   load_patch(patch, 3, 1, 4, 8, 11);
  141.   STRUCT_ASSIGN(*(object->min), patch->p[3]->coords);
  142.   STRUCT_ASSIGN(*(object->max), patch->p[3]->coords);
  143.   for (i = 0; i <= INTERVALS; POSINC(i))
  144.   {
  145.     u = (real) i / (real) INTERVALS;
  146.     b0 = BLEND0(u);
  147.     b1 = BLEND1(u);
  148.     CUBIC(patch, 0, u, k0);
  149.     CUBIC(patch, 2, u, k2);
  150.     MULTIPLY(patch->p[3]->coords, b0, k4);
  151.     MULTIPLY(patch->p[4]->coords, b1, k5);
  152.     MULTIPLY(patch->p[7]->coords, b0, k6);
  153.     MULTIPLY(patch->p[8]->coords, b1, k7);
  154.     SUBTRACT(k0, k4, k5, k0);
  155.     SUBTRACT(k2, k6, k7, k2);
  156.     if (i == 0)
  157.       j = 1;
  158.     else
  159.       j = 0;
  160.     do
  161.     {
  162.       v = (real) j / (real) INTERVALS;
  163.       CUBIC(patch, 1, v, k1);
  164.       CUBIC(patch, 3, v, k3);
  165.       b2 = BLEND0(v);
  166.       b3 = BLEND1(v);
  167.       f.x = k0.x * b2 + k1.x * b0 + k2.x * b3 + k3.x * b1;
  168.       f.y = k0.y * b2 + k1.y * b0 + k2.y * b3 + k3.y * b1;
  169.       f.z = k0.z * b2 + k1.z * b0 + k2.z * b3 + k3.z * b1;
  170.       object->max->x = MAX(object->max->x, f.x);
  171.       object->max->y = MAX(object->max->y, f.y);
  172.       object->max->z = MAX(object->max->z, f.z);
  173.       object->min->x = MIN(object->min->x, f.x);
  174.       object->min->y = MIN(object->min->y, f.y);
  175.       object->min->z = MIN(object->min->z, f.z);
  176.       POSINC(j);
  177.     }
  178.     while (j <= INTERVALS);
  179.   }
  180.   /* Adjust dimensions */
  181.   if (ABS(object->max->x - object->min->x) < threshold_distance)
  182.     object->max->x += threshold_distance;
  183.   if (ABS(object->max->y - object->min->y) < threshold_distance)
  184.     object->max->y += threshold_distance;
  185.   if (ABS(object->max->z - object->min->z) < threshold_distance)
  186.     object->max->z += threshold_distance;
  187.   center.x = (object->max->x + object->min->x) * 0.5;
  188.   center.y = (object->max->y + object->min->y) * 0.5;
  189.   center.z = (object->max->z + object->min->z) * 0.5;
  190.   object->max->x += (object->max->x - center.x) * CORRECTION;
  191.   object->max->y += (object->max->y - center.y) * CORRECTION;
  192.   object->max->z += (object->max->z - center.z) * CORRECTION;
  193.   object->min->x += (object->min->x - center.x) * CORRECTION;
  194.   object->min->y += (object->min->y - center.y) * CORRECTION;
  195.   object->min->z += (object->min->z - center.z) * CORRECTION;
  196. }
  197.